﻿using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Crmf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using NLog;
using RestSharp;

namespace FreeDream.Common.Helper
{
    public class HttpWebHelper
    {
        #region 1.0 Base Get Func
        private static ILogger _logger = LogManager.GetCurrentClassLogger();
        private static string SendGet(string parameter, string url)
        {
            try
            {
                parameter = (parameter.IndexOf('?') > -1) ? parameter : ("?" + parameter);
                WebRequest request = WebRequest.Create(url + parameter);
                byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(parameter);
                request.Method = "GET";
                WebResponse response = request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8"));
                string str = reader.ReadToEnd();
                reader.Close();
                response.Close();
                return str;
            }
            catch (Exception ex)
            {
                _logger.Error("[SendGet 请求失败]", ex);
                return null;
            }
        }
        #endregion

        #region 2.0 Base Post Func
        private static async Task<string> SendPost(string url, string data, string contentType)
        {
            //当请求码不为
            try
            {
                string statuCode = "";
                WebRequest request = WebRequest.Create(url);
                request.Method = "POST";
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                    ServicePointManager.CheckCertificateRevocationList = false;
                    ServicePointManager.DefaultConnectionLimit = 512;
                    ServicePointManager.Expect100Continue = false;
                }
                byte[] bytes = Encoding.UTF8.GetBytes(data);
                request.ContentType = contentType;
                request.ContentLength = bytes.Length;
                Stream requestStream = await request.GetRequestStreamAsync();
                requestStream.Write(bytes, 0, bytes.Length);
                requestStream.Close();
                var response = await request.GetResponseAsync() as HttpWebResponse;
                if (response != null)
                {
                    requestStream = response.GetResponseStream();
                    statuCode = response.StatusCode.ToString();
                    StreamReader reader = new StreamReader(requestStream, Encoding.UTF8);
                    string str = await reader.ReadToEndAsync();
                    reader.Close();
                    requestStream.Close();
                    response.Close();
                    //如果返回信息为空 则返回状态码
                    return string.IsNullOrEmpty(str) ? statuCode : str;
                }
                return "";
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("【Request Fail】Response：{0}|URL:{1}|Params:{2}|Type:{3}", ex.Message, url, data,
                    contentType), ex);
                return "";
            }
        }
        #endregion

        #region 3.0 HttpWebRequest POST请求
        private static string PostData(string url, string param, string contentype)
        {
            try
            {
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                    ServicePointManager.CheckCertificateRevocationList = false;
                    ServicePointManager.DefaultConnectionLimit = 512;
                    ServicePointManager.Expect100Continue = false;
                }
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = contentype;
                request.Timeout = 180 * 1000;
                string paraUrlCoded = param;
                byte[] payload = Encoding.UTF8.GetBytes(paraUrlCoded);
                if (string.IsNullOrEmpty(param))
                {
                    request.ContentLength = 0;
                }
                else
                {
                    request.ContentLength = payload.Length;
                }
                Stream writer = request.GetRequestStream();
                writer.Write(payload, 0, payload.Length);
                writer.Close();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream s = response.GetResponseStream();
                string strDate = "";
                string strValue = "";
                StreamReader reader = new StreamReader(s, Encoding.UTF8);
                while ((strDate = reader.ReadLine()) != null)
                {
                    strValue += strDate + "\r\n";
                }
                if (string.IsNullOrWhiteSpace(strValue))
                {
                    return JsonConvert.SerializeObject(new
                    {
                        code = -100,
                        message = " Response return empty",
                        total = 0,
                        timespan = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                    });
                }
                return strValue;
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("【Request Fail】Response：{0}|URL:{1}", ex.Message, url), ex);
                return JsonConvert.SerializeObject(new
                {
                    code = -101,
                    message = ex.Message,
                    total = 0,
                    timespan = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                });
            }
        }
        #endregion

        #region 2.0 POST数据
        /// <summary>
        /// POST数据
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="url">请求路径</param>
        /// <param name="param">参数</param>
        /// <param name="contentpye">报文类型</param>
        /// <returns></returns>
        public static T PostData<T>(string url, string param, string contentpye = "application/json;charset=UTF-8")
        {
            var setting = new JsonSerializerSettings();
            //解决枚举类型序列化转为数字的问题
            setting.Converters.Add(new StringEnumConverter());
            _logger.Debug($"[PostData<{typeof(T).FullName}>] Request:{url}--{param}");
            var retdata = PostData(url, param, contentpye);
            if (string.IsNullOrEmpty(retdata))
            {
                return default(T);
            }
            _logger.Debug($"[PostData<{typeof(T).FullName}>] Response:{url}--{param}--{retdata}");
            return JsonConvert.DeserializeObject<T>(retdata);
        }
        #endregion

        #region 3.0 GET请求 HttpWebRequest
        private static string GetRequest(string url)
        {
            try
            {
                //_logger.Debug($"Urls:{url}");
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.ContentType = "application/json;charset=UTF-8";
                request.Accept = "*/*";
                request.ProtocolVersion = HttpVersion.Version10;
                request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)";
                request.Timeout = 180 * 1000;
                string responseStr = "";
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
                    ServicePointManager.CheckCertificateRevocationList = false;
                    ServicePointManager.DefaultConnectionLimit = 512;
                    ServicePointManager.Expect100Continue = false;
                }
                //跳过验证
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                    {
                        responseStr = reader.ReadToEnd();
                    }
                }
                return responseStr;
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("【Request Fail】Response：{0}|URL:{1}", ex.Message, url), ex);
                return null;
            }
        }


        #endregion

        #region 4.0 GET数据
        public static T GetResult<T>(string url)
        {
            var retdata = GetRequest(url);
            if (string.IsNullOrEmpty(retdata))
            {
                return default(T);
            }
            return JsonConvert.DeserializeObject<T>(retdata);
        }
        #endregion

        /// <summary>
        /// ReSharp
        /// </summary>
        /// <param name="url"></param>
        /// <param name="func"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static async Task<string> ReSharpPost(string url, string func, string data)
        {
            try
            {
                var client = new RestClient(url);
                var request = new RestRequest(func, Method.Post);
                request.AddHeader("Content-Type", "application/json");
                request.AddParameter("application/json", data, ParameterType.RequestBody);
                // 执行请求
                var response = await client.ExecuteAsync(request);
                var content = response.Content; // raw content as string
                return content;
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("【Request Fail】Response：{0}|URL:{1}|Params:{2}|", ex.Message, url, data), ex);
                return "";
            }
        }

        public static async Task<string> WebRequestPostSent(string url, string data)
        {
            return await SendPost(url, data, "application/json");
        }

        public static async Task<T> WebRequestPost<T>(string url, string data)
        {
            var retdata = await WebRequestPostSent(url, data);
            _logger.Debug($"WebRequestPost URL:{url},Request:{data}");
            if (string.IsNullOrEmpty(retdata))
            {
                return default(T);
            }
            _logger.Debug($"WebRequestPost Response:{retdata}");
            return JsonConvert.DeserializeObject<T>(retdata);
        }

        

    }
}
